package com.alibaba.csp.sentinel.dashboard.rule.zookeeper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@Component
public class ZookeeperOptUtil {
	
	@Autowired
    private CuratorFramework zkClient;
	
	public <T extends RuleEntity> List<T> getRules(String app,Class<T> clazz) throws Exception {
		String path = ZookeeperConfigUtil.getPath(app,getPath(clazz));
		try{
			byte[] bytes = zkClient.getData().forPath(path);
			if (null != bytes) {
				String s = new String(bytes);
				return JSON.parseArray(s, clazz);
			}
		}catch(KeeperException ignore){
		}
		return Collections.emptyList();
	}
	
	public <T extends RuleEntity> void publish(String app, List<T> rules,Class<T> clazz) throws Exception {
		AssertUtil.notEmpty(app, "app name cannot be empty");
		String path = ZookeeperConfigUtil.getPath(app, getPath(clazz));
		Stat stat = zkClient.checkExists().forPath(path);
		if (stat == null) {
			zkClient.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, null);
		}
		List<JSONObject> list = new ArrayList<>();
		for (RuleEntity r:rules) {
			String json = JSON.toJSONString(r);
			JSONObject obj = JSON.parseObject(json);
			if(!obj.containsKey("rule")){
				obj.put("rule", r.toRule());
			}
			list.add(obj);
		}
		byte[] data = CollectionUtils.isEmpty(rules) ? "[]".getBytes() : JSON.toJSONString(list).getBytes();
		zkClient.setData().forPath(path, data);
	}
	
	public static String getPath(Class<?> clazz) {
		return clazz.getSimpleName().replace("Entity", "");
	}
	
}
